package com.syl.auth.filter;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.syl.auth.authorization.SmallAuthenticationToken;
import com.syl.auth.model.LoginData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @ClassName SmallAuthenticationProcessingFilter
 * @Description 认证入口
 * @Author YunLong
 * @Date 2023/5/3 11:03
 */
@Slf4j
public class SmallAuthenticationProcessingFilter extends UsernamePasswordAuthenticationFilter {
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

        log.debug("开始认证。");
        if (!request.getMethod().equals(HttpMethod.POST.name())) {
            throw new AuthenticationServiceException(
                    "Authentication method not supported: " + request.getMethod());
        }

        if (!request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)) {
            throw new AuthenticationServiceException(
                    "Authentication contentType not supported: " + request.getContentType());
        }

        LoginData loginData = new LoginData();
        ObjectMapper objectMapper = new ObjectMapper();
        // 未知字段不报错
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        try {
            loginData = objectMapper.readValue(request.getInputStream(), LoginData.class);
        } catch (IOException e) {
            throw new AuthenticationServiceException(
                    "loginDataJson to LoginData failed");
        }

        String username = loginData.getUsername();
        String password = loginData.getPassword();
        username = username == null ? "" : username;
        password = password == null ? "" : password;
        username = username.trim();


        SmallAuthenticationToken smallAuthenticationToken = new SmallAuthenticationToken(username, password);
        smallAuthenticationToken.setLoginData(loginData);

        return this.getAuthenticationManager().authenticate(smallAuthenticationToken);
    }
}
